package com.goldsprite.gameframeworks.ecs.component;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.goldsprite.gameframeworks.ecs.enums.SpriteDrawType;
import com.goldsprite.gameframeworks.utils.Pivot;
import com.goldsprite.gameframeworks.utils.math.Vector2;
import com.goldsprite.gameframeworks.utils.math.Vector2Int;
import com.goldsprite.gameframeworks.assets.GameAssetManager;
import com.goldsprite.gameframeworks.assets.GameRes;
import com.goldsprite.gameframeworks.assets.MTexture;
import com.goldsprite.gameframeworks.utils.*;

public class SpriteComponent extends RenderableComponent {

	public static final TextureRegion emptyRegion = new TextureRegion();
	private TextureRegion region = emptyRegion;//材质
	private final Vector2 scale = Vector2.One();
	private final Vector2 textureSize = Vector2.One();//大小
	private final Vector2 size = Vector2.One();
	private final Vector2Int spriteFace = new Vector2Int(1, 1);
	private Pivot pivot = Pivot.Center;

	private Color color = new Color(Color.WHITE);

	private NinePatch ninePatchRegion;
	public float ninePatchRegionWidthPercent = 1;
	private SpriteDrawType drawType = SpriteDrawType.Region;

	// 工具向量
	private final Vector2Int realFace = new Vector2Int(1, 1);
	private final Vector2 flipOriginOffset = new Vector2();
	private final Vector2 regionSelfUVFix = new Vector2();
	private final Vector2 renderScl = new Vector2();
	private final Vector2 renderSize = new Vector2();

	public TextureRegion getRegion() {
		return region;
	}

	public void setRegion(GameRes res) {
		MTexture tex = GameAssetManager.getInstance().getTexture(res);
		region = new TextureRegion(tex);
	}
	public void setRegion(TextureRegion region) {
//		//为了序列化的准备
//		if(!(region.getTexture() instanceof MTexture)) {
//			throw new IllegalArgumentException("必须设置一个源材质为MTexture的TextureRegion");
//		}
		this.region = region;
	}

	public Vector2Int getSpriteFace() {
		return spriteFace;
	}

	public void setSpriteFace(int spriteFaceX, int spriteFaceY) {
		spriteFace.set(spriteFaceX, spriteFaceY);
	}

	public Vector2Int getRealFace() {
		return (Vector2Int) realFace.set(getTransform().getFace()).scl(spriteFace);
	}

	public Vector2 getFlipOriginOffset() {
		return flipOriginOffset;
	}

	public void updateRegionFlip() {
		updateRegionFlip(getRegion());
	}

	public void updateRegionFlip(TextureRegion region) {
		if (region == null) return;

		boolean flipX, flipY;
		if (getRealFace().x >= 0) {
			flipX = region.isFlipX();
		} else {
			flipX = !region.isFlipX();
		}
		if (getRealFace().y >= 0) {
			flipY = region.isFlipY();
		} else {
			flipY = !region.isFlipY();
		}

		region.flip(flipX, flipY);
	}

	public Vector2 getLeftDownPos() {
		if (region == null) return leftDownPos.set(getTransform().getPosition());

		// 计算翻转实际偏移
		flipOriginOffset.set(originOffset.x, originOffset.y);

		// 翻转则镜像偏移值
		if (region.isFlipX()) flipOriginOffset.x = getTextureSize().x - originOffset.x;
		if (region.isFlipY()) flipOriginOffset.y = getTextureSize().y - originOffset.y;

		// 计算精灵拉伸以及trans拉伸
		flipOriginOffset.scl(scale).scl(getTransform().getScale());

		// 计算图片自身半宽高
		if (pivot.equals(Pivot.Center)) {
			regionSelfUVFix.set(getTextureSize()).div(2);
			// 计算精灵拉伸以及trans拉伸
			regionSelfUVFix.scl(scale).scl(getTransform().getScale());
			if (region.isFlipX()) regionSelfUVFix.x *= -1;
			if (region.isFlipY()) regionSelfUVFix.y *= -1;
		} else if (pivot.equals(Pivot.LeftDown)) {
			regionSelfUVFix.set(0);
		}

		// 返回左下位置
		return leftDownPos.set(
			getTransform().getPosition().x - flipOriginOffset.x - regionSelfUVFix.x,
			getTransform().getPosition().y - flipOriginOffset.y - regionSelfUVFix.y
		);
	}

	public Vector2 getRenderScl() {
		return renderScl.set(scale).scl(getTransform().getScale());
	}
	public Vector2 getRenderSize() {
		return renderSize.set(getTextureSize()).scl(getRenderScl());
	}

	public Vector2 getTextureSize() {
		return textureSize.set(region.getRegionWidth(), region.getRegionHeight());
	}

	public Vector2 getScale() {
		return scale;
	}

	public void setScale(float sclX, float sclY) {
		this.scale.set(sclX, sclY);
	}

	public void setSize(float sizeX, float sizeY) {
		this.size.set(sizeX, sizeY);
	}

	public Pivot getPivot() {
		return pivot;
	}

	public void setPivot(Pivot pivot) {
		this.pivot = pivot;
	}

	public NinePatch getNinePatchRegion() {
		return ninePatchRegion;
	}
	public void setNinePatchRegion(GameRes resId) {
		drawType = SpriteDrawType.NinePatch;
		int[] edge = resId.getNinePatchEdge();
		setRegion(resId);
		this.ninePatchRegion = new NinePatch(region, edge[0], edge[1], edge[2], edge[3]);
	}
	public void setDrawType(SpriteDrawType type) {
		this.drawType = type;
	}

	public Color getColor() {
		return color;
	}

	public void setColor(Color color) {
		this.color = color;
	}
	public void setAlpha(float alpha) {
		this.color.a = alpha;
	}

	@Override
	public void render(Batch batch, float delta) {
		//跳过未启用与未初始化精灵
		if(!isEnable() || emptyRegion.equals(region)){
			return;
		}

		//应用精灵翻转
		updateRegionFlip();
		//绘制: 中心转左下原点坐标, 计算拉伸
		Vector2 leftDownPos = getLeftDownPos();
		Vector2 texSize = getTextureSize();
		Vector2 renderScl = getRenderScl();
		Vector2 renderSize = getRenderSize();

		//独有color
		Color oldColor = batch.getColor();
		batch.setColor(color);

		if(drawType == SpriteDrawType.Region){
			batch.draw(region, leftDownPos.x, leftDownPos.y, renderSize.x, renderSize.y);
		}
		else if(drawType == SpriteDrawType.NinePatch){
			float zero = ninePatchRegionWidthPercent == 0 ? 0 : 1;
			ninePatchRegion.draw(batch,
				leftDownPos.x, leftDownPos.y,
				0, 0,
				texSize.x * ninePatchRegionWidthPercent, texSize.y,
				renderScl.x * zero, renderScl.y,
				0);
		}

		//设回color
		batch.setColor(oldColor);
	}
}
